/*******************************************************************************
 * File:      phy_engine.c                                                     *
 * Function:  a simple physical engine                                         *
 * Author:    kvmaker                                                          *
 * Email:     kvmaker@gmail.com                                                *
 * Data:      24/Feb/2012                                                      *
 *                                                                             *
 * Copyright: kvmaker                                                          *
 *                                                                             *
 * Licensed under the Apache License, Version 2.0 (the "License");             *
 * you may not use this file except in compliance with the License.            *
 * You may obtain a copy of the License at                                     *
 *                                                                             *
 *    http://www.apache.org/licenses/LICENSE-2.0                               *
 *                                                                             *
 * Unless required by applicable law or agreed to in writing, software         *
 * distributed under the License is distributed on an "AS IS" BASIS,           *
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.    *
 * See the License for the specific language governing permissions and         *
 * limitations under the License.                                              *
 ******************************************************************************/
/*******************************************************************************
 *                               INCLUDE                                       *
 ******************************************************************************/
#include "phy_engine.h"

/*******************************************************************************
 *                               PUBLIC_FUNCTION                               *
 ******************************************************************************/
UINT32 phy_engine_init(PHY_ENGINE *engine, UINT32 weight,
                       POINT      *start,  VECTOR *speed, VECTOR *force)
{
    engine->weight = weight;

    engine->start_point.x = start.x;
    engine->start_point.y = start.y;

    engine->start_speed.x = speed.x;
    engine->start_speed.y = speed.y;

    engine->force.x = force.x;
    engine->force.y = force.y;

    engine->acc.x   = engine->force.x / engine->weight;
    engine->acc.y   = engine->force.y / engine->weight;

    engine->state = PHY_ENGINE_STATE_STOP;
    return CT_RET_SUCC;
}

UINT32 phy_engine_start(PHY_ENGINE *engine)
{
    engine->start_tick = CT_GET_TICK();

    engine->current_point.x = engine->start_point.x;
    engine->current_point.y = engine->start_point.y;

    engine->state = PHY_ENGINE_STATE_RUN;
    return CT_RET_SUCC;
}

UINT32 phy_engine_update(PHY_ENGINE *engine)
{
    UINT32 delt_time;

    delt_time = CT_GET_TICK() - engine->start_tick;

    engine->current_speed.x = engine->start_speed.x + engine->acc.x * delt_time;
    engine->current_speed.y = engine->start_speed.y + engine->acc.y * delt_time;

    engine->current_point.x =   engine->start_point.x + engine->start_speed.x * delt_time
                              + (engine->acc.x * delt_time * delt_time) >> 1;
    engine->current_point.y =   engine->start_point.y + engine->start_speed.y * delt_time
                              + (engine->acc.y * delt_time * delt_time) >> 1;

    return CT_RET_SUCC;                              
}

UINT32 phy_engine_restart(PHY_ENGINE *engine, VECTOR *force)
{
    UINT32 delt_time;
    VECTOR current_speed;

    /*(1) update speed and location */
    phy_engine_update(engine);

    /*(2) retart this engine*/
    phy_engine_init(engine, engine->weight, 
                    &engine->current_point, &engine->current_speed, 
                    force);
    phy_engine_start(engine);

    return CT_RET_SUCC;
}

UINT32 phy_engine_stop(PHY_ENGINE *engine)
{
    engine->state = PHY_ENGINE_STATE_STOP;

    return CT_RET_SUCC;
}

